package com.demo.pong.utils


import spock.lang.Shared
import spock.lang.Specification

import java.security.KeyPair
import java.security.NoSuchAlgorithmException
import java.security.PrivateKey
import java.security.PublicKey

class EncryptionUtilTest extends Specification{

    @Shared
    KeyPair keyPair
    @Shared
    PublicKey publicKey
    @Shared
    PrivateKey privateKey

    def setup() throws NoSuchAlgorithmException {
        keyPair = EncryptionUtil.generateRsaKeyPair()
        publicKey = keyPair.public
        privateKey = keyPair.private
    }

    def "generateRsaKeyPair should generate valid key pair"() {
        expect:
        keyPair != null
        publicKey != null
        privateKey != null
    }

    def "getRsaPublicKeyString should return Base64 encoded string for valid public key"() {
        when:
        String publicKeyString = EncryptionUtil.getRsaPublicKeyString(publicKey)

        then:
        publicKeyString != null
        !publicKeyString.isEmpty()
    }

    def "getRsaPrivateKeyString should return Base64 encoded string for valid private key"() {
        when:
        String privateKeyString = EncryptionUtil.getRsaPrivateKeyString(privateKey)

        then:
        privateKeyString != null
        !privateKeyString.isEmpty()
    }

    def "hashWithSha256 should return hashed string for valid plaintext"() throws NoSuchAlgorithmException {
        given:
        String plaintext = "test"

        when:
        String hashed = EncryptionUtil.hashWithSha256(plaintext)

        then:
        hashed != null
        !hashed.isEmpty()
    }

    def "encodeBase64 should return Base64 encoded string for valid plain text"() {
        given:
        String plainText = "test"

        when:
        String encoded = EncryptionUtil.encodeBase64(plainText)

        then:
        encoded != null
        !encoded.isEmpty()
    }

    def "decodeBase64 should return plain text for valid Base64 text"() {
        given: "A plain text to encode"
        String plainText = "test"

        when: "The plain text is encoded to Base64"
        String encoded = EncryptionUtil.encodeBase64(plainText)

        and: "The encoded Base64 text is decoded back to plain text"
        String decoded = EncryptionUtil.decodeBase64(encoded)

        then: "The decoded string should match the original plain text"
        decoded == plainText
    }

    def "test getRsaPublicKeyString handles exception"() {
        setup:
        PublicKey publicKey = Mock(PublicKey) {
            getEncoded() >> { throw new Exception("Mocked exception") }
        }

        when:
        def result = EncryptionUtil.getRsaPublicKeyString(publicKey)

        then:
        result == null // Expect the result to be null due to exception
    }

    def "test getRsaPrivateKeyString handles exception"() {
        setup:
        PrivateKey privateKey = Mock(PrivateKey) {
            getEncoded() >> { throw new Exception("Mocked exception") }
        }

        when:
        def result = EncryptionUtil.getRsaPrivateKeyString(privateKey)

        then:
        result == null // Expect the result to be null due to exception
    }
}

